package com.caocaog.market.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.caocaog.market.entity.GoodsCategories;
import com.caocaog.market.mapper.GoodsCategoriesMapper;
import com.caocaog.market.service.GoodsCategoriesService;
import com.caocaog.market.vo.LabelAndValueVo;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.CheckFailedException;
import org.jeecg.common.system.base.entity.FieldRedisItem;
import org.jeecg.common.system.base.service.impl.GenericServiceImpl;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 商品分类
 *
 * @author chechen
 * @date 2022-04-13
 */
@Slf4j
@Service
public class GoodsCategoriesServiceImpl extends GenericServiceImpl<GoodsCategoriesMapper, GoodsCategories> implements GoodsCategoriesService {

    @Override
    public IPage<GoodsCategories> queryGoodsCategoriesPage(Page<GoodsCategories> page, GoodsCategories goodsCategories) {
        page.setOrders(ORDER_ITEM_LIST);
        return super.baseMapper.queryGoodsCategoriesPage(page, goodsCategories);
    }


    @Override
    public synchronized List<GoodsCategories> getShowGoodsCategoriesByShopId(String shopId) {
        return this.selectListByFieldCache(shopId, CacheConstant.GOODS_CATEGORIES_LIST_BY_SHOP_ID).stream()
                .filter(goodsCategories -> "1".equals(goodsCategories.getIsShow()))
                .sorted(Comparator.comparing(GoodsCategories::getSort).thenComparing(GoodsCategories::getCreateTime).reversed())
                .collect(Collectors.toList());
    }


    @Override
    public List<LabelAndValueVo> getCategoriesLV(String shopId) {
        return super.selectListByFieldCache(shopId, CacheConstant.GOODS_CATEGORIES_LIST_BY_SHOP_ID).stream()
                .sorted(Comparator.comparing(GoodsCategories::getSort).thenComparing(GoodsCategories::getCreateTime).reversed())
                .map(categories -> new LabelAndValueVo(categories.getName(), categories.getId()))
            .collect(Collectors.toList());
    }


    @Override
    public GoodsCategories insertGoodsCategories(GoodsCategories goodsCategories) {
        log.info("获取list缓存，并检查名称是否重复");
        List<GoodsCategories> goodsCategoriesList = super.selectListByFieldCache(goodsCategories.getShopId(), CacheConstant.GOODS_CATEGORIES_LIST_BY_SHOP_ID);
        if (super.isRepeatField(goodsCategoriesList, goodsCategories, GoodsCategories::getName)) {
            throw new CheckFailedException("已有名为「" + goodsCategories.getName() + "」的商品分类");
        }

        int insertRecordCount = super.insertCache(goodsCategories);
        if (insertRecordCount == 0) {
            log.error("新增商品分类失败");
            log.error(goodsCategories.toString());
            return null;
        }

        return super.getByIdCache(goodsCategories.getId());
    }


    @Override
    public GoodsCategories updateGoodsCategories(GoodsCategories goodsCategories) {
        log.info("获取list缓存，并检查商品分类是否存在，以及名称是否重复");
        List<GoodsCategories> goodsCategoriesList = super.selectListByFieldCache(goodsCategories.getShopId(), CacheConstant.GOODS_CATEGORIES_LIST_BY_SHOP_ID);
        if (super.isExist(goodsCategoriesList, goodsCategories.getId()))
            throw new CheckFailedException("未找到此商品分类信息");
        if (super.isRepeatField(goodsCategoriesList, goodsCategories, GoodsCategories::getName))
            throw new CheckFailedException("已有名为「" + goodsCategories.getName() + "」的商品分类信息");

        int updateRecordCount = super.updateCache(goodsCategories);
        if (updateRecordCount == 0) {
            log.error("更新商品分类失败, id-> " + goodsCategories.getId());
            log.error(goodsCategories.toString());
        }

        GoodsCategories byIdCache = super.getByIdCache(goodsCategories.getId());
        final String key = CacheConstant.GOODS_LIST_BY_CATEGORIES_ID + CommonConstant.DOUBLE_COLON + byIdCache.getId();
        // 如果关闭了显示，并且缓存中有数据，则删除 GOODS_LIST_BY_CATEGORIES_ID 缓存
        if ("0".equals(byIdCache.getIsShow()) && this.redisUtil.hasKey(key)) {
            this.redisUtil.del(key);
        }
        return byIdCache;
    }


    @Override
    public int deleteGoodsCategories(String... ids) {

        // 删除 GOODS_LIST_BY_CATEGORIES_ID 缓存
        this.redisUtil.del(Arrays.stream(ids).map(id ->
                CacheConstant.GOODS_LIST_BY_CATEGORIES_ID + CommonConstant.DOUBLE_COLON + id
        ).toArray(String[]::new));
        // 删除 GOODS_BASE_LIST_BY_CATEGORIES_ID 缓存
        this.redisUtil.del(Arrays.stream(ids).map(id ->
                CacheConstant.GOODS_BASE_LIST_BY_CATEGORIES_ID + CommonConstant.DOUBLE_COLON + id
        ).toArray(String[]::new));

        return super.deleteByIdsAllCache(ids);
    }


    @Override
    public String[] getGoodsCategoriesIdsByShopIds(String... shopIds) {
        return Arrays.stream(shopIds)
                .distinct()
                .map(shopId -> this.selectListByFieldCache(shopId, CacheConstant.GOODS_CATEGORIES_LIST_BY_SHOP_ID))
                .flatMap(Collection::stream)
                .map(GoodsCategories::getId)
                .toArray(String[]::new);
    }


    @Override
    public String getName() {
        return "商品分类";
    }

    @Override
    public List<FieldRedisItem<GoodsCategories>> getAllFieldCacheList() {
        return Arrays.asList(
                FieldRedisItem.build(GoodsCategories::getId, CacheConstant.GOODS_CATEGORIES_INFO, true),
                FieldRedisItem.build(GoodsCategories::getShopId, CacheConstant.GOODS_CATEGORIES_LIST_BY_SHOP_ID)
        );
    }

    /**
     * 固定排序字段
     */
    private static final List<OrderItem> ORDER_ITEM_LIST = Arrays.asList(
            new OrderItem("sort", false),
            new OrderItem(CommonConstant.DEFAULT_ORDER_COLUMN, false)
    );

}
